package com.jsh.erp.service.sequence;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.TimeUnit;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.support.atomic.RedisAtomicLong;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;

/**
 * 序列号工具类
 * @author GMaya
 */
@Service
public class SequenceUtil {

    @Resource
    private RedisTemplate redisTemplate;

    /**
     * 获取序列号
     * 例子：假如需要获取订单号NO20200320000001等数据，前缀NO，后面的每天从1开始自增
     * 调用getCode("NO") 返回 202003200000001,0的个数根据自己业务量设置
     * 自己将返回的字符串再次拼接上NO即可！序列号 = 'NO'+getCode("NO")
     * @param keyPrefix 关键词前缀
     * @return 序列号
     */
    public String getCode(String keyPrefix) {
        // 当前日期加填充完0的值
        return new SimpleDateFormat("yyyyMMdd").format(new Date()) + getSequence(keyPrefix);
    }

    /**
     * 根据关键词前缀设置redis的key
     * @param keyPrefix
     * @return
     */
    private String getSequence(String keyPrefix) {
        // 如果你的序列号需要每个月从1开始计算，那么时间就变为yyyyMM。
        String currentDate = new SimpleDateFormat("yyyyMMdd").format(new Date());
        // 得到这个key的value值
        Long num = getIncrementNum("seq:" + keyPrefix + currentDate);
        // 填充这个值，一般情况下一天的序列号3位差不多，所以前面几位需要填充0
        return getSequence(num);
    }

    /**
     * 查询redis中这个key，并且加1返回
     * @param key
     * @return
     */
    private Long getIncrementNum(String key) {
        // 不存在准备创建 键值对
        RedisAtomicLong entityIdCounter = new RedisAtomicLong(key, redisTemplate.getConnectionFactory());
        Long counter = entityIdCounter.get(); // 自增加1
        if ((null == counter || counter.longValue() == 0)) {
            // 初始设置过期时间
            Long s = entityIdCounter.incrementAndGet();
            entityIdCounter.expire(1, TimeUnit.DAYS);// 单位天
            return s;
        }
        return counter;
    }

    public void incrementNum(String key) {
        // 如果你的序列号需要每个月从1开始计算，那么时间就变为yyyyMM。
        String currentDate = new SimpleDateFormat("yyyyMMdd").format(new Date());
        // 得到这个key的value值
        RedisAtomicLong entityIdCounter = new RedisAtomicLong("seq:" + key + currentDate, redisTemplate.getConnectionFactory());
        entityIdCounter.incrementAndGet();
    }

    public void incrementNumByType(String key) {
        // 如果你的序列号需要每个月从1开始计算，那么时间就变为yyyyMM。
//        String currentDate = new SimpleDateFormat("yyyyMMdd").format(new Date());
        // 得到这个key的value值
        RedisAtomicLong entityIdCounter = new RedisAtomicLong("seq:" + key , redisTemplate.getConnectionFactory());
        entityIdCounter.incrementAndGet();
    }

    static final int DEFAULT_LENGTH = 4; // 填充0的总位数

    /**
     * 将数值前面填充0
     * @param seq
     * @return
     */
    private static String getSequence(long seq) {
        String str = String.valueOf(seq);
        int len = str.length();
        // 一般业务量不会超过8位数
        if (len >= DEFAULT_LENGTH) {
            return str;
        }
        // 前面填充0，保证数值一直是8位数
        int rest = DEFAULT_LENGTH - len;
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < rest; i++) {
            sb.append('0');
        }
        sb.append(str);
        return sb.toString();
    }
}

